package com.ikun.hosscheduling.controller;


import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.ikun.common.entity.Scheduling;
import com.ikun.hosscheduling.service.SchedulingService;
import com.ikun.hosscheduling.utils.DoctorScheduleInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDate;
import java.util.*;

@RestController
@RequestMapping("/Scheduling")
public class SchedulingController {

    @Autowired
    private SchedulingService schedulingService;


    @RequestMapping("/add-surplus/{date}/{docId}/{timeId}")
    public Scheduling addSurplus(@PathVariable String date, @PathVariable Integer docId, @PathVariable Integer timeId) {
        return schedulingService.addSurplus(date, docId, timeId);
    }

    @RequestMapping("/reduce-surplus/{date}/{docId}/{timeId}")
    public Scheduling reduceSurplus(@PathVariable String date, @PathVariable Integer docId, @PathVariable Integer timeId) {
        return schedulingService.reduceSurplus(date, docId, timeId);
    }

    /**
     * 根据日期获取排版信息
     *
     * @param date 要查询的日期
     * @return 返回的是当前排班表的所有信息
     */
    @GetMapping("date/{date}")
    public ResponseEntity<List<Scheduling>> getScheduleByDate(@PathVariable("date") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date) {

        List<Scheduling> schedule = schedulingService.getScheduleByDate(date);
        if (schedule.isEmpty()) {
            return ResponseEntity.ok().build();
        }
        return ResponseEntity.ok(schedule);
    }


    /**
     * 获取一周内上班的医生
     *
     * @return 一周内所有值班医生的列表
     */
    @GetMapping("/doctors/weekly")
    public ResponseEntity<List<Scheduling>> getWeeklyDoctors() {
        // 获取一周内的日期列表
        List<LocalDate> datesThisWeek = new ArrayList<>();
        LocalDate currentDate = LocalDate.now();
        for (int i = 0; i < 7; i++) {
            datesThisWeek.add(currentDate.plusDays(i));
        }

        // 初始化医生集合 值班医生
        Set<Scheduling> doctorsOnDuty = new HashSet<>();

        // 遍历日期列表，查询每天有值班的医生
        for (LocalDate date : datesThisWeek) {
            List<Scheduling> doctors = schedulingService.getScheduleByDate(date);
            doctorsOnDuty.addAll(doctors);
        }
        // 返回一周内上班的医生列表
        return new ResponseEntity<>(new ArrayList<>(doctorsOnDuty), HttpStatus.OK);
    }


    /**
     * 通过医生id 查询一周的排版信息
     *
     * @param dockerId 医生id
     * @return 返回的是医生一周排班时间
     */
    @GetMapping("/scheduling/{dockerId}/{positionId}")
    public ResponseEntity<DoctorScheduleInfo> getSchedulingByDockerId(@PathVariable Long dockerId, Long positionId) {
        // 获取一周内的日期列表
        List<LocalDate> datesThisWeek = new ArrayList<>();
        LocalDate currentDate = LocalDate.now();
        for (int i = 0; i < 7; i++) {
            datesThisWeek.add(currentDate.plusDays(i));
        }

        //该医生一周的排版信息
        List<Scheduling> schedulingList = new ArrayList<>();
        for (LocalDate date : datesThisWeek) {
            List<Scheduling> dailyScheduling = schedulingService.getScheduleByDocker(dockerId, date, positionId);
            schedulingList.addAll(dailyScheduling);
        }

        //计算每天的余号数以及是否有余号
        HashMap<LocalDate, Integer> yuHao = new HashMap<>();
        for (LocalDate date : datesThisWeek) {
            int numYuHao = calculateTheNumberOfRemainingNumbers(schedulingList, date);
            yuHao.put(date, numYuHao);
        }

        System.err.println("一周日期" + datesThisWeek);
        System.err.println("余号：" + yuHao);
        System.err.println("医生一周排版信息：" + schedulingList);

        DoctorScheduleInfo doctorScheduleInfo = new DoctorScheduleInfo(schedulingList, yuHao);

        System.err.println("doctorScheduleInfo：" + doctorScheduleInfo);
        // 返回一周内那个医生上班的列表
        return ResponseEntity.ok(doctorScheduleInfo);
    }

    /**
     * 计算余号数
     */
    public static int calculateTheNumberOfRemainingNumbers(List<Scheduling> schedulingList, LocalDate date) {
        // 设置默认余号数
        int remainingNumber = 0;
        String stringDate = date.toString();
        for (Scheduling scheduling : schedulingList) {
            if (scheduling.getDate().toString().equals(stringDate)) {
                String code = scheduling.getCode();
                Map<String, String> stringMapCode = code(code);
                for (String number : stringMapCode.values()) {
                    remainingNumber += Integer.parseInt(number);
                }
            }
        }
        return remainingNumber;
    }

    /**
     * 将余号放到map里面
     */
    public static Map<String, String> code(String code) {
        JsonObject jsonObject = JsonParser.parseString(code).getAsJsonObject();
        // 使用 LinkedHashMap 保持插入顺序
        LinkedHashMap<String, String> mapCode = new LinkedHashMap<>();
        // 遍历 JSON 对象，提取每个时间段的余号数量
        for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
            // 检查值是否为字符串
            if (entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isString()) {
                // 时间段id
                String timeSlotId = entry.getKey();
                // 获取余号数量
                String slots = entry.getValue().getAsString();
                mapCode.put(timeSlotId, slots);
            }
        }
        return mapCode;
    }
}
